﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using ToastNotifications;
using ToastNotifications.Lifetime;
using ToastNotifications.Lifetime.Clear;
using ToastNotifications.Position;
using ToastNotifications.Messages;
using ToastNotifications.Core;

namespace ScratchNet
{
    /// <summary>
    /// Toast类是对Notifier实例对象的再封装。这种封装提供了以下好处：
    /// 1. 简化使用
    /// Toast类隐藏了Notifier的复杂配置细节，提供了更简单、更直观的方法来显示不同类型的通知（如信息、成功、警告、错误）。
    /// 2. 默认配置
    /// Toast类在构造函数中设置了默认的通知配置（如位置、显示时长、最大通知数量等），这样用户就不需要每次显示通知时都进行配置。
    /// 3. 方法封装
    /// Toast类提供了多个方法来显示不同类型的通知，这些方法封装了Notifier的相应方法，使得调用更加方便。
    /// 4. 资源管理
    /// Toast类在OnUnloaded方法中提供了资源释放的机制，确保在窗口卸载时释放Notifier资源，避免内存泄漏。
    /// 5. 扩展性
    /// 如果需要，可以很容易地在Toast类中添加新的方法或属性，以扩展其功能，而不需要直接修改Notifier的使用方式。
    /// 6. 解耦
    /// 通过封装，Toast类将通知逻辑与具体的Notifier实现解耦，使得在未来替换或修改通知库时更加容易。
    /// 通过封装，Toast类提供了一个更高层次的抽象，使得在应用程序中显示通知变得更加简单和一致。
    /// </summary>
    public class Toast : INotifyPropertyChanged
    {
        // 显示和管理通知消息
        private readonly Notifier _notifier;

        public Toast()
        {
            // 创建了一个Notifier对象并配置了其属性
            _notifier = new Notifier(cfg =>
            {
                // 设置通知消息的位置，这里设置为在主窗口的底部中心，偏移量为X轴0像素，Y轴30像素。
                cfg.PositionProvider = new WindowPositionProvider(
                    parentWindow: Application.Current.MainWindow,
                    corner: Corner.BottomCenter,
                    offsetX: 0,
                    offsetY: 30);

                // 设置通知消息的显示时长和最大通知数量，这里设置为显示4秒且最多显示1条通知。
                cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor(
                    notificationLifetime: TimeSpan.FromSeconds(4),
                    maximumNotificationCount: MaximumNotificationCount.FromCount(1));

                // 设置用于调度通知的调度器，这里使用当前应用程序的调度器。
                cfg.Dispatcher = Application.Current.Dispatcher;

                // 设置显示选项，这里设置为不是顶层窗口，宽度为450像素。
                cfg.DisplayOptions.TopMost = false;
                cfg.DisplayOptions.Width = 450;
            });

            // 调用ClearMessages方法清除所有现有通知。
            _notifier.ClearMessages(new ClearAll());
        }

        public void OnUnloaded()
        {
            // 在窗口卸载时调用，释放_notifier资源。
            _notifier.Dispose();
        }

        // 显示信息通知。可以带选项或不带选项。
        public void ShowInformation(string message)
        {
            _notifier.ShowInformation(message);
        }

        public void ShowInformation(string message, MessageOptions opts)
        {
            _notifier.ShowInformation(message, opts);
        }

        // 显示成功通知。可以带选项或不带选项。
        public void ShowSuccess(string message)
        {
            _notifier.ShowSuccess(message);
        }

        public void ShowSuccess(string message, MessageOptions opts)
        {
            _notifier.ShowSuccess(message, opts);
        }

        // 根据消息内容清除特定通知。
        internal void ClearMessages(string msg)
        {
            _notifier.ClearMessages(new ClearByMessage(msg));
        }

        // 显示警告通知。必须带选项。
        public void ShowWarning(string message, MessageOptions opts)
        {
            _notifier.ShowWarning(message, opts);
        }

        // 显示错误通知。可以带选项或不带选项。
        public void ShowError(string message)
        {
            _notifier.ShowError(message);
        }

        public void ShowError(string message, MessageOptions opts)
        {
            _notifier.ShowError(message, opts);
        }


        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        // 清除所有通知。
        public void ClearAll()
        {
            _notifier.ClearMessages(new ClearAll());
        }
    }
}
